package net.cathackers.devel.scmp.chat.impl.xmpp.iqcomponent;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.apache.log4j.Logger;
import net.cathackers.devel.scmp.factories.SCMPFactory;

/**
 * This class will be used basically to load classes at run-time from FileSystem
 * specific locations Don't use the System ClassLoader for two reasons : 1-
 * It'll cause a security hole in the system 2- It can only load classes in the
 * CLASSPATH ( CLASSPATH changes at run-time doesn't affect the class loader )
 */

public class FileSystemLoader extends ClassLoader {
    private String dirPath_;
    private Logger logger_;

    public FileSystemLoader(String dirPath) {
        super();
        logger_ = SCMPFactory.getLogger(this);
        String sep = String.valueOf(File.separatorChar);
        if (!dirPath.endsWith(sep)) {
            dirPath = dirPath + sep;
        }
        dirPath_ = dirPath;
    }

    @SuppressWarnings("deprecation")
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        logger_.debug("Trying to load class " + name + " from '" + dirPath_ +"'");
        byte[] buf = getFile(name);
        Class<?> cls = null;
        cls = defineClass(buf, 0, buf.length);
        logger_.debug("Class " + cls.getSimpleName() + " was loaded successfully");
        return cls;
    }

    private byte[] getFile(String name) throws ClassNotFoundException {
        File file = new File(dirPath_ + name);
        byte[] buf = new byte[(int) file.length()];
        try {
            FileInputStream fis = new FileInputStream(file);
            fis.read(buf);
        } catch (FileNotFoundException e) {
            logger_.error("File " + dirPath_ + file.getName() + " couldn't be found");
            throw new ClassNotFoundException();
        } catch (IOException e) {
            logger_.error("File " + dirPath_ + file.getName() + " couldn't be read");
            throw new ClassNotFoundException();
        }
        return buf;
    }
}